# -*- coding: cp1252 -*-
# Python 2.6
import wx
import sys
from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
import os, time
#import thread
from KThread import *

from functions import getcbtext, setcbtext

class SortedListCtrl(wx.ListCtrl, ColumnSorterMixin,ListCtrlAutoWidthMixin):
    def __init__(self, parent,fileList):
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
        ColumnSorterMixin.__init__(self, len(fileList))
        ListCtrlAutoWidthMixin.__init__(self)
        self.itemDataMap = fileList

    def GetListCtrl(self):
        return self

class mp3GUI(wx.Frame):
    fileList = []
    def __init__(self, parent, id, title,playerInstance):
        root = wx.App()
        wx.Frame.__init__(self, parent, id, title, size=(650, 380))

        hbox = wx.BoxSizer(wx.VERTICAL)

        panel = wx.Panel(self, -1)

        self.list = SortedListCtrl(panel,self.fileList)
        self.list.InsertColumn(0, 'file', 635)

        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.playClickedFile)

        self.updateFileList()

        gauge = wx.Gauge(panel, range=100, size=(100, 10))
        hbox.Add(self.list, 1, wx.EXPAND)
        hbox.Add(gauge, 0, wx.EXPAND)
        panel.SetSizer(hbox)

        
        #panel2 = wx.Panel(self, 0)
        #hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        #gauge = wx.Gauge(panel2, range=1000, size=(200, 15))
        #hbox2.Add(gauge,1,wx.EXPAND)
        #panel2.SetSizer(hbox2)

        self.CreateStatusBar()
        self.SetStatusText("This is the statusbar")

        MN_ADD_DIR  =   101
        MN_ADD_FILE =   102
        MN_QUIT     =   100

        file_menu = wx.Menu()
        menubar = wx.MenuBar()
        file_menu.Append(MN_ADD_DIR, "Add &Directory ...", "Select a directory to add to the list")
        file_menu.Append(MN_ADD_FILE, "Add &Files ...", "Select files add to the list")
        file_menu.AppendSeparator()
        file_menu.Append(MN_QUIT, "&Quit", "Quit the application")

        self.Bind(wx.EVT_MENU, self.pickDirectory, id=MN_ADD_DIR)
        self.Bind(wx.EVT_MENU, self.pickFile, id=MN_ADD_FILE)
        self.Bind(wx.EVT_MENU, self.onExit, id=MN_QUIT)

        self.Bind(wx.EVT_CLOSE, self.onExit)    # user / app quits
        self.Bind(wx.EVT_QUERY_END_SESSION, self.onExit) # system shutdown, veto
        self.Bind(wx.EVT_END_SESSION, self.onExit) # system shutdown, no veto

        menubar.Append(file_menu, '&File')
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)
        self.playing = False
        self.root = root
        self.playerInstance = playerInstance
        self.gauge = gauge        

    def onExit(self,event):
        self.need_abort = True
        if self.playing or self.playerInstance.cur_song.playing:
            self.playerInstance.cur_song.stop()
            self.songGaugeThread.kill()
            print "\nStopped music."
        
        print "Closing application..."
        self.Destroy()

    def start(self):
        self.root.MainLoop()

    def updateFileList(self):
        items = self.list.itemDataMap

        for i in xrange(len(items)):
            index = self.list.InsertStringItem(sys.maxint, items[i])
            #self.list.SetStringItem(index, 1, data[1])
            #self.list.SetStringItem(index, 2, data[2])
            self.list.SetItemData(index, i)

    def GetItemText(self, item):
        return self.list.itemDataMap[item]

    def pickFile(self, event):             # Call "Choose file..." dialog
        temp_location = wx.EmptyString
        # for multiple formats: wildcard="*.mp3;*.wav"
        
        tfiles = wx.FileDialog(self, "Choose one or more .mp3 files", temp_location, wildcard="*.mp3", style=wx.FD_MULTIPLE)
        if (tfiles.ShowModal() == wx.ID_OK):
            filepaths = tfiles.GetPaths()
        print filepaths
        self.list.itemDataMap = list(set(filepaths))
        # append selected file and update the list
        #self.fileList.append(tfile)
        self.updateFileList()

    def pickDirectory(self, event):             # Call "Choose directory..." dialog
        temp_location = wx.EmptyString
        tdir = wx.DirDialog(self, "Choose a directory with mp3 files", temp_location, style=wx.DD_DIR_MUST_EXIST)
        if (tdir.ShowModal() == wx.ID_OK):
            path = tdir.GetPath()
        
            tfileList = []
            for (dirpath, dirnames, filenames) in os.walk(path):
                for tfile in filenames:
                    if tfile.endswith(".mp3") or tfile.endswith(".wav"):
                        tfileList.append(dirpath+"/"+tfile)
        #print tfileList
        self.list.itemDataMap = list(set(tfileList))
        # append selected file and update the list
        #self.fileList.append(tfile)
        self.updateFileList()

    def playClickedFile(self, event):   # play selected file in listbox with playerInstance
        try:
            if self.playerInstance.cur_song.playing:
                self.playerInstance.cur_song.stop()
                self.songGaugeThread.kill()
        except AttributeError:
            pass

        self.playerInstance.playFile(str(event.GetItem().GetText()))
        
        if self.playerInstance.cur_song.playing:
            #thread.start_new_thread(self.playingSongLoop,())
            self.songGaugeThread = KThread(target=self.playingSongLoop)
            self.songGaugeThread.start()
            

    def playingSongLoop(self):
        self.gauge.SetRange(self.playerInstance.cur_song.length)
        while self.playerInstance.cur_song.playing:
            self.gauge.SetValue(self.playerInstance.cur_song.position)
            self.playing = self.playerInstance.cur_song.playing
            time.sleep(0.8)
        
        

class mp3GUI2:
    fileList = []
    def __init__(self, root, playerInstance):
        #root.protocol("WM_DELETE_WINDOW", self.onExit)  # cleanup on closing the window

        # actual window menu
        #menubar = Menu(root)
        
        # create a pulldown menu, and add it to the menu bar
        #filemenu = Menu(menubar, tearoff=0)
        #filemenu.add_command(label="Open a directory ...", command=self.pickOnlyDirectory)
        #filemenu.add_command(label="Add a directory ...", command=self.pickDirectory)
        #filemenu.add_command(label="Add a file ...", command=self.pickFile)
        #filemenu.add_separator()
        #filemenu.add_command(label="Exit", command=self.onExit)
        #menubar.add_cascade(label="File", menu=filemenu)

        # create more pulldown menus
        editmenu = Menu(menubar, tearoff=0)
        editmenu.add_command(label="Copy selected", command=self.copySelectedFiles)
        editmenu.add_command(label="Paste clipboard", command=self.pasteFiles)
        editmenu.add_command(label="Remove selected", command=self.removeSelectedFiles)
        menubar.add_cascade(label="Edit", menu=editmenu)

        #helpmenu = Menu(menubar, tearoff=0)
        #helpmenu.add_command(label="About", command=hello)
        #menubar.add_cascade(label="Help", menu=helpmenu)

        # display the menu
        root.config(menu=menubar)


        # create contextmenu (right-click on the listbox)
        contextMenu = Menu(root, tearoff=0)
        contextMenu.add_command(label="Remove", command=self.removeSelectedFiles) # , command=next) etc...
        contextMenu.add_command(label="Copy path", command=self.copySelectedFiles)
        contextMenu.add_command(label="Paste files", command=self.pasteFiles)
        #popup.add_separator()



        # main frame, contains:
        # - a listbox with files
        # - a scrollbar for the listbox (vertical only at the moment)
        frame = Frame(root)
        #pbar = ProgressBar(frame,200,20,playerInstance.songDuration,"red")
        #pbar.pack()
        listbox = Listbox(frame, selectmode=EXTENDED, width=60, heigh=10)
        listbox.pack(side=LEFT, fill=BOTH, expand=1)
        listbox.bind("<Double-Button-1>", self.playClickedFile)
        listbox.bind("<Button-3>", self.spawnContextMenu)
        
        scrollbar = Scrollbar(frame)
        scrollbar.pack(side=RIGHT, fill=BOTH)
        listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.yview)
        
        frame.pack(side=TOP, fill=BOTH,expand=1)

        # second frame, containing the buttons
        #frame2 = Frame(root)
        # initialize buttons
        #btn_file = Button(text='Load a file', command=self.pickFile)
        #btn_dir = Button(text='Load a directory', command=self.pickDirectory)

        # bind buttons to GUI
        #btn_file.pack(side=LEFT,fill=X,expand=1)
        #btn_dir.pack(side=RIGHT,fill=X,expand=1)
        #frame2.pack(side=BOTTOM, fill=BOTH)

        w = Label(root, text="Right-click to display menu, doubleclick a file to play", width=60, height=1)
        w.pack()

        self.playing = False
        self.listbox = listbox
        self.root = root
        self.playerInstance = playerInstance
        self.contextMenu = contextMenu
        #self.pbar = pbar

        self.playerloop()
    
    def start(self):
        self.root.mainloop()
    
    def onExit(self):
        if self.playing:
            self.playerInstance.cur_song.stop()
            print "\nStopped music."
        
        print "Closing application..."
        self.root.destroy()
        self.mainloop = False

    def playerloop(self): # actual GUI loop
        interval = 800 # initiate loop with interval in msecs
        
        if not self.playerInstance.cur_song == "<NONE>":
            self.playing = self.playerInstance.cur_song.playing
        else:
            self.playing = False

        if self.playing:
            self.secondsplaying = time.time() - self.playerInstance.songStartingTime

            #print str(int(self.secondsplaying)) +":"+ str(int(self.playerInstance.songDuration))
        else:
            self.songStartingTime = 0
            self.songDuration = 0
            self.secondsplaying = 0

        #self.pbar.setValue(self.secondsplaying)
        
        self.root.after(interval, self.playerloop)

    def spawnContextMenu(self,event):
        try:
            self.contextMenu.tk_popup(event.x_root+45, event.y_root+10, 0)
        finally:
            # make sure to release the grab (Tk 8.0a1 only)
            self.contextMenu.grab_release()
    
    def pickFile(self):             # Call "Choose file..." dialog
        tfile = askopenfilename(filetypes=[('All supported', '.mp3 .wav'), ('.mp3 files', '.mp3'), ('.wav files','.wav')])

        # append selected file and update the list
        self.fileList.append(tfile)
        self.updateFileList()
    
    def pickDirectory(self):        # Call "Choose directory..." dialog
        path = askdirectory()

        # check if path is not empty and stuff?

        # for each file you find, add it
        tfileList = []
        for (dirpath, dirnames, filenames) in os.walk(path):
            for tfile in filenames:
                if tfile.endswith(".mp3") or tfile.endswith(".wav"):
                    tfileList.append(dirpath+"/"+tfile)

        # append selected files and update the list
        self.fileList += tfileList
        self.updateFileList()

    def playClickedFile(self, event):   # play selected file in listbox with playerInstance
        self.playerInstance.playFile(self.listbox.get(event.widget.curselection()))

    def updateFileList(self):       # update the listbox
        # First we clear the list, then we add the files one by one
        self.listbox.delete(0,END)
        
        for item in self.fileList:
            self.listbox.insert(END, item)

    def getSelectedFiles(self):     # get selected files in the listbox
        return [self.listbox.get(x) for x in self.listbox.curselection()]

    def removeFiles(self, files):   # remove given files from the listbox
        # subtract the selection from our paths
        # note: this method distorts the order or the listbox
        self.fileList = list(set(self.fileList) - set(files))
        self.updateFileList()

    def removeSelectedFiles(self):  # remove selected files
        while len(self.listbox.curselection())>0:
            self.listbox.delete(self.listbox.curselection()[0])

    def copySelectedFiles(self):  # remove selected files
        setcbtext('\r\n'.join([self.listbox.get(x) for x in self.listbox.curselection()]))

    def pasteFiles(self):
        pastelist = getcbtext().split('\r\n')
        pastelist.reverse()
        for item in xrange(len(pastelist)):
            self.listbox.insert(int(self.listbox.index(ACTIVE))+1, pastelist[item])
